﻿using System.Collections;
using System.Linq.Expressions;
using System.Net;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Linq;

namespace Leo.Common
{
    public static class ExtensionFunctions
    { 
        public static string ToLineText(this object obj)
        {
            Type type = obj.GetType();
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.AppendLine(type.FullName);
            foreach (PropertyInfo propertyInfo in type.GetProperties())
            {
                stringBuilder.AppendLine(string.Format("[{0}]{1}", propertyInfo.Name.PadRight(20, ' '), propertyInfo.GetValue(obj, null)));
            }
            return stringBuilder.ToString();
        }
         
        public static IDictionary<string, object> ToDictionary(this object obj, IDictionary<string, object> dictionary = null, Action<ObjectToDictionaryEntry> beforeAdding = null, Action<ObjectToDictionaryEntry, IDictionary<string, object>> afterAdded = null)
        {
            ObjectToDictionaryConverter objectToDictionaryConverter = new ObjectToDictionaryConverter(obj);
            if (beforeAdding != null)
            {
                objectToDictionaryConverter.BeforeEntryInsert += beforeAdding;
            }
            if (afterAdded != null)
            {
                objectToDictionaryConverter.AfterEntryInsert += afterAdded;
            }
            return objectToDictionaryConverter.ToDictionary(dictionary);
        }
         
        
        public static string Join<T>(this IEnumerable<T> self, Expression<Func<T, object>> express, char seperator)
        {
            IEnumerable<object> values = self.Select(express.Compile());
            return string.Join<object>(new string(seperator, 1), values);
        }
         
        public static decimal TruncateValue(this decimal d, int scale)
        {
            decimal d2 = (decimal)Math.Pow(10.0, (double)scale);
            decimal d3 = decimal.Truncate(d);
            return decimal.Truncate((d - d3) * d2) / d2 + d3;
        }
         
        public static ArrayList BubbleSort(this ArrayList r)
        {
            for (int i = 0; i < r.Count; i++)
            {
                bool flag = false;
                for (int j = r.Count - 2; j >= i; j--)
                {
                    if (string.CompareOrdinal(r[j + 1].ToString(), r[j].ToString()) < 0)
                    {
                        object value = r[j + 1];
                        r[j + 1] = r[j];
                        r[j] = value;
                        flag = true;
                    }
                }
                if (!flag)
                {
                    break;
                }
            }
            return r;
        }
        
        public static byte[] HexString2ByteArray(this string s)
        {
            int num = s.Length;
            if (num % 2 != 0)
            {
                s += " ";
                num++;
            }
            int num2 = num / 2;
            byte[] array = new byte[num2];
            for (int i = 0; i < num2; i++)
            {
                array[i] = Convert.ToByte(s.Substring(i * 2, 2), 16);
            }
            return array;
        }
         
        public static string ByteArray2HexString(this byte[] bs)
        {
            StringBuilder stringBuilder = new StringBuilder();
            foreach (byte b in bs)
            {
                stringBuilder.Append(b.ToString("x").PadLeft(2, '0'));
            }
            return stringBuilder.ToString();
        }
         
        public static string ElementValue(this XElement ele, string name)
        {
            if (ele == null)
            {
                return string.Empty;
            }
            XElement xelement = ele.Element(name);
            if (xelement == null)
            {
                return string.Empty;
            }
            return xelement.Value;
        }
          
        public static string ElementValue(this XElement ele, string name, string defaultvalue)
        {
            if (ele == null)
            {
                return defaultvalue;
            }
            XElement xelement = ele.Element(name);
            if (xelement == null)
            {
                return defaultvalue;
            }
            return xelement.Value;
        }
         
        public static decimal ElementValue(this XElement ele, string name, decimal defaultvalue)
        {
            return Convert.ToDecimal(ele.ElementValue(name, defaultvalue.ToString()));
        }
         
        public static int ElementValue(this XElement ele, string name, int defaultvalue)
        {
            return Convert.ToInt32(ele.ElementValue(name, defaultvalue.ToString()));
        }
         
        public static bool ElementValue(this XElement ele, string name, bool defaultvalue)
        {
            string text = ele.ElementValue(name);
            if (string.IsNullOrEmpty(text))
            {
                return defaultvalue;
            }
            string a = text.ToLower();
            bool result;
            if (!(a == "false"))
            {
                if (!(a == "true"))
                {
                    int num = 0;
                    result = (int.TryParse(text, out num) && num > 0);
                }
                else
                {
                    result = true;
                }
            }
            else
            {
                result = false;
            }
            return result;
        }
         
        //public static FuncResult ToFailResult(this IPromptInfo prompt)
        //{
        //    int resultType = (int)prompt.ResultType;
        //    string code = (resultType == 0) ? "0500" : resultType.ToString().PadLeft(4, '0');
        //    return FuncResult.Fail(prompt.CustomMessage, code);
        //}
         
        //public static FuncResult<T> ToFailResult<T>(this IPromptInfo prompt)
        //{
        //    int resultType = (int)prompt.ResultType;
        //    string code = (resultType == 0) ? "0500" : resultType.ToString().PadLeft(4, '0');
        //    return FuncResult.Fail<T>(prompt.CustomMessage, code);
        //}
         
        //public static FuncResult ToFailResult(this IPromptInfo prompt, string defaultMessage)
        //{
        //    int resultType = (int)prompt.ResultType;
        //    string code = (resultType == 0) ? "0500" : resultType.ToString().PadLeft(4, '0');
        //    return FuncResult.Fail(prompt.CustomMessage ?? defaultMessage, code);
        //}
         
        //public static FuncResult<T> ToFailResult<T>(this IPromptInfo prompt, string defaultMessage)
        //{
        //    int resultType = (int)prompt.ResultType;
        //    string code = (resultType == 0) ? "0500" : resultType.ToString().PadLeft(4, '0');
        //    return FuncResult.Fail<T>(prompt.CustomMessage ?? defaultMessage, code);
        //}
         
        public static void ForEach<T>(this IEnumerable<T> array, Action<T> action)
        {
            if (array == null || !array.Any<T>())
            {
                return;
            }
            foreach (T obj in array)
            {
                action(obj);
            }
        }
         
        public static bool IsEnum(this Type type)
        {
            Type type2;
            return type.IsEnum(out type2);
        }
         
        public static bool IsEnum(this Type type, out Type enumType)
        {
            if (type.IsEnum)
            {
                enumType = type;
                return true;
            }
            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                Type underlyingType;
                enumType = (underlyingType = Nullable.GetUnderlyingType(type));
                if (underlyingType.IsEnum)
                {
                    return true;
                }
            }
            if (Enumeration.IsAssignableFrom(type))
            {
                enumType = type;
                return true;
            }
            enumType = null;
            return false;
        }
    }
}
